package springweb.config;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import springweb.repository.mysql.dao.LoginUserDao;
import springweb.repository.mysql.entity.LoginUser;
import springweb.repository.mysql.entity.Resource;
import springweb.repository.mysql.entity.Role;
import springweb.repository.mysql.mapper.LoginUserMapper;


public class ShiroDbRealm extends AuthorizingRealm {
	
	@Autowired
	private LoginUserMapper loginUserMapper;

	@Autowired
	private LoginUserDao loginUserDao;
	
	private static final Logger log =Logger.getLogger(ShiroDbRealm.class);
	
    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
//        LoginUser user = loginUserMapper.selectByUserName(token.getUsername());
//        DigestUtils.md5Digest
//        Md5Hash md =new Md5Hash(token.getPassword());
//        SimpleHash sHash= new SimpleHash("MD5", token.getPassword());
        
        log.info("================guyue========"+token.getUsername()+"==="+String.valueOf( token.getPassword()));
        LoginUser user= loginUserDao.selectByUserName(token.getUsername());
        
//        LoginUser user1= loginUserDao.selectByUserName(token.getUsername());
//        ShiroUser shiroUser = shiroFactory.shiroUser(user);
//        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUserName(), user.getPassWord(), getName());
        
        
//        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
//		com.daimon.user.model.User user = userDao.findByUserName(token
//				.getUsername());
//
        log.info("ceshi======"+user);
		if (user != null) {
			return new SimpleAuthenticationInfo(user.getUserName(),
					user.getPassWord(), getName());
		} else {
//			throw new UnknownAccountException("No account found for user ["
//					+ token.getUsername() + "]");
			return null;
		}
        
    }

    /**
     * 权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//        IShiro shiroFactory = ShiroFactroy.me();
        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
        log.info(shiroUser.getLoginName());
        LoginUser user= loginUserMapper.selectByUserName(shiroUser.getLoginName());
        List<Role> roleList = user.getRoles();

        Set<String> permissionSet = new HashSet<>();
        Set<String> roleNameSet = new HashSet<>();

        for (Role roleId : roleList) {
            List<Resource> permissions = roleId.getResources();
            if (permissions != null) {
                for (Resource permission : permissions) {
                        permissionSet.add(permission.getPath());
                        log.info(permission.getPath());
                }
            }
            roleNameSet.add(roleId.getName());
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionSet);
        info.addRoles(roleNameSet);
        return info;
        
        
//        String userName = (String) principals.fromRealm(getName()).iterator()
//				.next();
//		com.daimon.user.model.User user = userDao.findByUserName(userName);
//		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//		for (Role role : user.getRoles()) {
//			info.addRole(role.getName());
//			for (Resource res : role.getResources()) {
//				info.addStringPermission(res.getPath());
//			}
//		}
//		return info;
    }

    /**
     * 设置认证加密方式
     */
    
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName("MD5");
//        md5CredentialsMatcher.set
//        md5CredentialsMatcher.setHashIterations(1024);
        super.setCredentialsMatcher(md5CredentialsMatcher);
    }
    
    
    /**
	 * 自定义Authentication对象，使得Subject除了携带用户的登录名外还可以携带更多信息.
	 */
	public static class ShiroUser implements Serializable {
		private static final long serialVersionUID = -1373760761780840081L;
		public Long id;
		public String loginName;
		public String name;
		
		
		

		public String getLoginName() {
			return loginName;
		}

		public void setLoginName(String loginName) {
			this.loginName = loginName;
		}

		public ShiroUser(Long id, String loginName, String name) {
			this.id = id;
			this.loginName = loginName;
			this.name = name;
		}

		public String getName() {
			return name;
		}

		/**
		 * 本函数输出将作为默认的<shiro:principal/>输出.
		 */
		@Override
		public String toString() {
			return loginName;
		}

		/**
		 * 重载hashCode,只计算loginName;
		 */
		@Override
		public int hashCode() {
			return Objects.hashCode(loginName);
		}

		/**
		 * 重载equals,只计算loginName;
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			ShiroUser other = (ShiroUser) obj;
			if (loginName == null) {
				if (other.loginName != null) {
					return false;
				}
			} else if (!loginName.equals(other.loginName)) {
				return false;
			}
			return true;
		}
	}
	
	public static void main(String[] args) {
		
		String admin="admin";
		
		System.out.println(SimpleHash.toBytes(admin).toString() );
		
		SimpleHash hash = new SimpleHash("MD5", admin);
		System.out.println(hash.toString());
		
	}
}
